package be.nvlooy.moviereminder.service.implementations;

import java.util.GregorianCalendar;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import be.nvlooy.moviereminder.entities.Collection;
import be.nvlooy.moviereminder.entities.Media;
import be.nvlooy.moviereminder.entities.Suggestion;
import be.nvlooy.moviereminder.entities.User;
import be.nvlooy.moviereminder.exception.ServiceException;
import be.nvlooy.moviereminder.service.BasicService;
import be.nvlooy.moviereminder.service.CollectionService;
import be.nvlooy.moviereminder.service.FriendshipService;
import be.nvlooy.moviereminder.service.SuggestionService;

@Service
public class SuggestionServiceImpl extends BasicService implements SuggestionService {
	
	private EntityManager em;
	
	private FriendshipService friendshipService;
	
	private CollectionService collectionService;

	@Autowired
	public void setFriendshipService(FriendshipService friendshipService) {
		this.friendshipService = friendshipService;
	}
	
	@Autowired
	public void setCollectionService(CollectionService collectionService) {
		this.collectionService = collectionService;
	}

	@Autowired
	public void setEntityManager(EntityManager em) {
		this.em = em;
	}
	
	@Override
	public boolean suggestionExists(User from, Collection collection) {
		Suggestion suggestion = null;
		Query query = em.createNamedQuery("Suggestion.findExisting");
		query.setParameter("from", from);
		query.setParameter("collection", collection);
		
		try {
			suggestion = (Suggestion) query.getSingleResult();
		}
		catch(javax.persistence.NoResultException ex) {}
		
		return suggestion != null;
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public Suggestion newSuggestion(User from, User to, Media media) {
		Suggestion suggestion = null;
		
		// do a friendshipcheck first
		if(!friendshipService.isFriendWith(from, to))
			throw new ServiceException("newSuggestionRejectedNoFriendship");
		
		// create a new collectionitem for the friend if needed
		Collection collection = collectionService.getCollectionItem(to, media);
		if(collection == null) {
			collection = collectionService.addMedia(to, media);
			
			try {
				em.persist(collection);
			}
			catch(RuntimeException e) {
				throw new ServiceException("newSuggestionCantAddCollection", e);
			}
		}
		else if(suggestionExists(from, collection)) {
			// you already suggested the exact same media
			throw new ServiceException("alreadySuggestedMedia");
		}
		
		// create a suggestion and link it to the (newly created) collection item
		suggestion = new Suggestion();
		suggestion.setCollection(collection);
		suggestion.setSuggestedBy(from);
		
		try {
			em.persist(suggestion);
		}
		catch(RuntimeException e) {
			throw new ServiceException("newSuggestionError", e);
		}
		
		return suggestion;
	}

}
